package com.supersystem.utils;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateUtils;


public class DateUtil {

    public static final String STANDARD_FORMAT = "yyyy-MM-dd";
    public static final String PRECISE_FORMAT = "yyyy-MM-dd HH:mm:ss";
    public static String format(java.util.Date date) {
        if (date != null) {
            return new SimpleDateFormat(STANDARD_FORMAT).format(date);
        }
        return "";
    }

    public static String formatDate(java.util.Date date) {
        return format(date);
    }

    public static String formatTime(java.util.Date date) {
        return formatPrecise(date);
    }

    public static String formatPrecise (java.util.Date date) {
        if (date != null) {
            return new SimpleDateFormat(PRECISE_FORMAT).format(date);
        }
        return "";
    }

    public static Date parseDate(String s) throws ParseException {
        return parse(s);
    }

    public static Date parse(String s) throws ParseException {
        if (StringUtils.isNotBlank(s)) {
            return new SimpleDateFormat(STANDARD_FORMAT).parse(s);
        }
        return null ;
    }

    /**
     * <li>方法描述：格式化日期为字符串
     *
     * @param d
     * @param s "yyyyMMdd" 、"yyyy-MM-dd HH:mm:ss"
     * @return
     */
    public static String formateToSpecificString(Date d, String s) {
        if (d == null) {
            return "" ;
        }
        if (StringUtils.isBlank(s)) {
            return format(d) ;
        }
        SimpleDateFormat sdf = new SimpleDateFormat(s);
        return sdf.format(d);
    }

    public static Date parseFromSpecificString(String s, String format) throws ParseException {
        if (StringUtils.isBlank(s)) {
            return null ;
        }
        SimpleDateFormat sdf ;
        if (StringUtils.isBlank(format)) {
            sdf = new SimpleDateFormat(format);
        } else {
            sdf = new SimpleDateFormat(STANDARD_FORMAT) ;
        }
        return sdf.parse(s);
    }

    public static int getInterval(Date begin, Date end, int field) {
        Calendar beginDate = Calendar.getInstance();
        beginDate.setTime(begin);

        Calendar endDate = Calendar.getInstance();
        endDate.setTime(end);

        beginDate = DateUtils.truncate(beginDate, field);
        endDate = DateUtils.truncate(endDate, field);

        int difference = 0;
        switch (field) {
            case Calendar.MONTH:
                int diffYear = endDate.get(Calendar.YEAR) - beginDate.get(Calendar.YEAR);
                int diffMonth = endDate.get(Calendar.MONTH) - beginDate.get(Calendar.MONTH);
                difference = diffYear * 12 + diffMonth;
                break;
            case Calendar.DAY_OF_YEAR:
                difference = getDaysBetween(beginDate, endDate);
                break ;
            default:
                throw new UnsupportedOperationException("this method is not implemented fully and doesn't support such a field.");
        }
        return difference;
    }

    public static int getDaysBetween(Calendar begin, Calendar end) {
        if (begin.after(end)) { // swap dates so that d1 is start and d2 is end
            Calendar swap = begin;
            begin = end;
            end = swap;
        }
        int days = end.get(Calendar.DAY_OF_YEAR) - begin.get(Calendar.DAY_OF_YEAR);
        int y2 = end.get(Calendar.YEAR);
        if (begin.get(Calendar.YEAR) != y2) {
            begin = (Calendar) begin.clone();
            do {
                days += begin.getActualMaximum(Calendar.DAY_OF_YEAR);
                begin.add(Calendar.YEAR, 1);
            } while (begin.get(Calendar.YEAR) != y2);
        }
        return days;
    }

    public static Date getDateAfterDays(Date date, int days) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.DAY_OF_MONTH, days);
        return calendar.getTime();
    }

    /**
     * 当前时间加小时数
     * @param date
     * @param hours
     * @return
     */
    public static Date getPlusDate(Date date,int hours){
    	Calendar calendar = Calendar.getInstance();
    	calendar.setTime(date);
    	calendar.add(Calendar.HOUR_OF_DAY, hours);
    	return calendar.getTime();
    }
    
    /**
     * 当前时间加分钟
     * @param date
     * @param hours
     * @return
     */
    public static Date getPlusDateOfMinute(Date date,int minute){
    	Calendar calendar = Calendar.getInstance();
    	calendar.setTime(date);
    	calendar.add(Calendar.MINUTE, minute);
    	return calendar.getTime();
    }

    /**
     * 比较两个时间的大小
     * d1>d2返回 true
     * d1<d2返回false
     * @param d1
     * @param d2
     * @return
     */
    public static int dateEqual(Date d1,Date d2){
    	Calendar calendar1 = Calendar.getInstance();
    	Calendar calendar2 = Calendar.getInstance();
    	calendar1.setTime(d1);
    	calendar2.setTime(d2);
    	return calendar1.compareTo(calendar2);
    }

    /**
     * 比较两个时间的大小 返回大数
     * @param d1
     * @param d2
     * @return
     */
    public static Date getHigherDate(Date d1,Date d2){
        if(dateEqual(d1,d2)>=0){
            return d1;
        }else{
            return d2;
        }
    }

    private static Calendar todayCalendar(boolean clearTime) {
        Calendar cd = Calendar.getInstance();
        if (clearTime) {
            cd.set(Calendar.HOUR, 0);
            cd.set(Calendar.MINUTE, 0);
            cd.set(Calendar.SECOND, 0);
            cd.set(Calendar.MILLISECOND, 0);
        }
        return cd ;
    }

    public static Date today(boolean clearTime) {
        return todayCalendar(clearTime).getTime();
    }

    public static Date yesterday(boolean clearTime) {
        return addDays(todayCalendar(clearTime), -1);
    }

    public static Date theDayBeforeYesterday(boolean clearTime) {
        return addDays(todayCalendar(clearTime), -2);
    }

    public static Date tomorrow(boolean clearTime) {
        return addDays(todayCalendar(clearTime), 1);
    }

    public static Date theDayAfterTomorrow(boolean clearTime) {
        return addDays(todayCalendar(clearTime), 2);
    }

    public static Date addDays(Calendar cd, int days) {
        cd.add(Calendar.DATE, days);
        return cd.getTime();
    }
}
